//
//  L0PlugSuitInputManagerRegistry.m
//  PlugSuit
//
//  Created by ∞ on 10/3/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "L0PlugSuitInputManagerRegistry.h"
#import "L0PlugSuitFlavor.h"

@implementation L0PlugSuitInputManagerRegistry

- (id) init {
	if (self = [super init]) {
		_plugIns = [NSMutableDictionary new];
		[self updateRegistry];
	}
	
	return self;
}

- (void) dealloc {
	[_plugIns release];
	[super dealloc];
}

- (BOOL) plugInsExistFor:(NSBundle*) app processID:(pid_t) pid {
	return L0PlugSuitIsCocoaApplication(pid) && ([_plugIns count] > 0);
}

- (void) updateRegistry {
	[_plugIns removeAllObjects];
	
	NSMutableArray* libraries = [NSMutableArray arrayWithArray:NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, YES)];
	[libraries removeObjectsInArray:NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES)];
	
	NSEnumerator* enu = [libraries objectEnumerator];
	NSString* libraryPath;
	
	while (libraryPath = [enu nextObject]) {
		libraryPath = [libraryPath stringByAppendingPathComponent:@"InputManagers"];
		[self updateWithPlugInsInDirectory:libraryPath];
	}
}

- (void) updateWithPlugInsInDirectory:(NSString*) dir {
	NSEnumerator* enu = [[[NSFileManager defaultManager] directoryContentsAtPath:dir] objectEnumerator];
	NSString* item;
	
	while (item = [enu nextObject]) {
		item = [dir stringByAppendingPathComponent:item];
		NSDictionary* info = [NSDictionary dictionaryWithContentsOfFile:[item stringByAppendingPathComponent:@"Info"]];
		NSString* bundleName = [info objectForKey:@"BundleName"];
		if (bundleName) {
			NSBundle* b = [NSBundle bundleWithPath:[item stringByAppendingPathComponent:bundleName]];
			NSString* ident;
			if (b && [b infoDictionary] && (ident = [[b infoDictionary] objectForKey:@"CFBundleIdentifier"])) {
				if (![ident isEqual:@"net.culater.SIMBL"] && ![_plugIns objectForKey:ident])
					[_plugIns setObject:b forKey:ident];
			}
		}
	}
}

- (void) loadPlugIns {
	if (![self inputManagersNeedLoading]) {
#ifdef L0PlugSuitDebug
		NSLog(@"[from PlugSuit] DEBUG: Mac OS X should already have loaded input managers. PlugSuit won't load or initialize them again.");
#endif
		return;
	}
	
	NSEnumerator* enu = [[_plugIns allValues] objectEnumerator];
	NSBundle* plugIn;
	
	while (plugIn = [enu nextObject]) {
#ifdef L0PlugSuitDebug
		NSLog(@"[from PlugSuit] DEBUG: Now loading input manager: %@", plugIn);
#endif
		if (![[self class] isEnabled:plugIn])
			continue;
		
		if ([plugIn load])
			[[plugIn principalClass] new]; // leaks the instance
	}
}

- (BOOL) inputManagersNeedLoading {
	long version;
	return (Gestalt(gestaltSystemVersionMinor, &version) == noErr) && version > 4;
}

- (BOOL) shouldLoadInputManagersAtPath:(NSString*) path {	
	static NSArray* localLibraries = nil;
	if (!localLibraries)
		localLibraries = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES) retain];
	
	NSEnumerator* enu = [localLibraries objectEnumerator];
	NSString* library;
	while (library = [enu nextObject]) {
		if ([path hasPrefix:library])
			return NO;
	}
	
	return YES;
}

- (NSDictionary*) registeredPlugIns {
	if (![self inputManagersNeedLoading])
		return [NSDictionary dictionary];
	return _plugIns;
}

@end
